package com.fita.entity.coupon;

import com.alibaba.fastjson.annotation.JSONField;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.DateUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fita.entity.order.Order;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 
 * @author dan
 *
 */
@Entity
@Table(name = "coupon")
public class Coupon {

    @Id
    @GeneratedValue
    private Long id;

    /** 名称 */
    private String name;

    /** 代码 */
    private String code;


    /** 生效时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date effectiveStartDate;

    /** 失效时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date effectiveEndDate;


    /** 优惠券名称 来自模版 */
    private String templateName;
    
    /** 批次名称 来自批次 */
    private String batchName;
    
    /** 实际抵扣金额 */
    private Integer amount;
    
    /** 优惠券批次 */
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JsonIgnore
    private CouponBatch batch;
    
    /** 优惠券模版 来自批次 */
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    @JsonIgnore
    private CouponTemplate template;
    
    /** 优惠券的状态 */
    @Enumerated(EnumType.ORDINAL)
    private CouponStatus status;
    
    /** 使用时间 */
	/** 失效时间 */
	@DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date useTime;
    
    /** 使用者ID */
    private Long userId;
    
    /** 使用者手机 */
    private String mobile;
    
    /** 使用者姓名 */
    private String userName;
    
    /**用户订单*/
    @ManyToOne(fetch = FetchType.LAZY)
    @JsonIgnore
    private Order order;
    
    @Column(name = "is_disabled")
    private Boolean disabled ;
    

    /**
     * 
     */
    public Coupon() {
    }

    /**
     * 
     * @param couponBatch
     */
    public Coupon(CouponBatch couponBatch) {
        this.templateName = couponBatch.getCouponTemplate().getName();
        this.batchName = couponBatch.getName();
        this.amount = couponBatch.getCouponTemplate().getAmount();
        this.effectiveStartDate = couponBatch.getEffectiveStartDate();
        this.effectiveEndDate = couponBatch.getEffectiveEndDate();
        this.batch = couponBatch;
        this.template = couponBatch.getCouponTemplate();
        this.status = CouponStatus.UNCLAIMED;
    }
    
    /**
     * 
     * @param userId
     * @param identification
     * @return
     */
    public Coupon identify(Long userId, String identification,String userName) {
        
    	this.mobile=identification;
    	this.userName=userName;
        
        // change coupon status
        this.status = CouponStatus.CLAIMED;
        
        if(this.batch.getExpireType().isFixedDate()) {
            
            this.effectiveStartDate = this.batch.getEffectiveStartDate();
            this.effectiveEndDate = this.batch.getEffectiveEndDate();
        }
        
        // if user exit, bind user & date
        if (userId != null) {
            
            this.userId = userId;
            
            if(!this.batch.getExpireType().isFixedDate()) {
                Date today = new Date();
                this.effectiveStartDate = today;
                this.effectiveEndDate = org.apache.commons.lang3.time.DateUtils.addDays(today, this.batch.getEffectiveDays());
            }
        }
        
	
        	this.code = this.id.toString() + this.effectiveEndDate.getTime();
    
       
        
        return this;
    }
    
    /**
     * 
     * @param identification
     * @return
     */
    public Coupon identify(String identification) {
        
        // change coupon status
        this.status = CouponStatus.CLAIMED;
        
        if(this.batch.getExpireType().isFixedDate()) {
            
            this.effectiveStartDate = this.batch.getEffectiveStartDate();
            this.effectiveEndDate = this.batch.getEffectiveEndDate();
        }
        
        return this;
    }

    /**
     * 
     * @param userId
     * @return
     */
    public Coupon bindUser(Long userId) {
        this.userId = userId;        
    	this.disabled=false;
        
        // change coupon status
        this.status = CouponStatus.CLAIMED;
        
        if (this.batch.getExpireType().isFixedDate()) {
            this.effectiveStartDate = this.batch.getEffectiveStartDate();
            this.effectiveEndDate = this.batch.getEffectiveEndDate();
        }else {
            Date today = new Date();
            this.effectiveStartDate = today;
            this.effectiveEndDate = org.apache.commons.lang3.time.DateUtils.addDays(today, this.batch.getEffectiveDays());
        }
        
        return this;
    }
    
    /**
     * 
     * @return
     */
    public Coupon use() {
        this.status = CouponStatus.USED;
        this.batch.setUsedAmount(this.batch.getUsedAmount() + 1);
        this.useTime = new Date();
        return this;
    }
    
    /**
     * Get rest days when coupon is effective
     *  
     * @return
     */
    @JSONField(serialize = false)
    public int getRestDay() {
        Date today = DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd");
        return (this.effectiveEndDate == null || today.after(this.effectiveEndDate)) ? -1 : (DateUtils.daysBetween(this.effectiveEndDate, DateUtils.parseDate(DateFormatUtils.format(new Date(), "yyyy-MM-dd"), "yyyy-MM-dd")) + 1);
    }

	/**
	 * 获取格式化价格
	 * @return
	 */
	@Transient
    public BigDecimal getPrettyAmount(){

    	if (amount == null){
    		return BigDecimal.ZERO;
		}
    	return new BigDecimal(amount).divide(new BigDecimal(100));
	}

	/**
	 * @return the id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @param code the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @return the effectiveStartDate
	 */
	public Date getEffectiveStartDate() {
		return effectiveStartDate;
	}

	/**
	 * @param effectiveStartDate the effectiveStartDate to set
	 */
	public void setEffectiveStartDate(Date effectiveStartDate) {
		this.effectiveStartDate = effectiveStartDate;
	}

	/**
	 * @return the effectiveEndDate
	 */
	public Date getEffectiveEndDate() {
		return effectiveEndDate;
	}

	/**
	 * @param effectiveEndDate the effectiveEndDate to set
	 */
	public void setEffectiveEndDate(Date effectiveEndDate) {
		this.effectiveEndDate = effectiveEndDate;
	}

	/**
	 * @return the templateName
	 */
	public String getTemplateName() {
		return templateName;
	}

	/**
	 * @param templateName the templateName to set
	 */
	public void setTemplateName(String templateName) {
		this.templateName = templateName;
	}

	/**
	 * @return the batchName
	 */
	public String getBatchName() {
		return batchName;
	}

	/**
	 * @param batchName the batchName to set
	 */
	public void setBatchName(String batchName) {
		this.batchName = batchName;
	}

	/**
	 * @return the amount
	 */
	public Integer getAmount() {
		return amount;
	}

	/**
	 * @param amount the amount to set
	 */
	public void setAmount(Integer amount) {
		this.amount = amount;
	}

	/**
	 * @return the batch
	 */
	public CouponBatch getBatch() {
		return batch;
	}

	/**
	 * @param batch the batch to set
	 */
	public void setBatch(CouponBatch batch) {
		this.batch = batch;
	}

	/**
	 * @return the template
	 */
	public CouponTemplate getTemplate() {
		return template;
	}

	/**
	 * @param template the template to set
	 */
	public void setTemplate(CouponTemplate template) {
		this.template = template;
	}

	/**
	 * @return the status
	 */
	public CouponStatus getStatus() {
		return status;
	}

	/**
	 * @param status the status to set
	 */
	public void setStatus(CouponStatus status) {
		this.status = status;
	}

	/**
	 * @return the useTime
	 */
	public Date getUseTime() {
		return useTime;
	}

	/**
	 * @param useTime the useTime to set
	 */
	public void setUseTime(Date useTime) {
		this.useTime = useTime;
	}

	/**
	 * @return the userId
	 */
	public Long getUserId() {
		return userId;
	}

	/**
	 * @param userId the userId to set
	 */
	public void setUserId(Long userId) {
		this.userId = userId;
	}

	/**
	 * @return the mobile
	 */
	public String getMobile() {
		return mobile;
	}

	/**
	 * @param mobile the mobile to set
	 */
	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	/**
	 * @return the userName
	 */
	public String getUserName() {
		return userName;
	}

	/**
	 * @param userName the userName to set
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}

	/**
	 * @return the order
	 */
	public Order getOrder() {
		return order;
	}

	/**
	 * @param order the order to set
	 */
	public void setOrder(Order order) {
		this.order = order;
	}

	/**
	 * @return the disabled
	 */
	public Boolean getDisabled() {
		return disabled;
	}

	/**
	 * @param disabled the disabled to set
	 */
	public void setDisabled(Boolean disabled) {
		this.disabled = disabled;
	}
    

    
}
